<script setup lang="ts">
import {dictApi} from "@/api/dict";
import {
  DataTableColumns,
  FormInst,
  FormRules,
  NButton,
  NFlex,
  NPopconfirm,
  NSpace,
  PaginationInfo,
  PaginationProps
} from "naive-ui";
import {SysDict} from "@/api/dict/types.ts";
import {clickCopyButton, deepClone, renderIcon, renderPermission, resetToNull} from "@/utils";
import {useRoute, useRouter} from "vue-router";
import {useDictStore} from "@/stores";

enum ModeTypeEnum {
  ADD = '新增',
  MODIFY = '修改'
}

interface PageQuery {
  keyword?: string
  dictStatus?: number
  parentId?: string
}

const router = useRouter();
const currentRoute = useRoute();
const dictStore = useDictStore();
const pageQuery = reactive<PageQuery>({
  keyword: undefined,
  dictStatus: undefined,
  parentId: "0"
})
const tableLoading = ref(false);
const tableColumns = ref<DataTableColumns<SysDict>>([
  {title: '字典名称', key: 'dictName'},
  {title: '字典编码', key: 'dictCode', render: row => tableDictCodeRender(row)},
  {
    title: '操作', key: 'action', align: 'center', render: row => tableActionRender(row)
  }
])
const tableData = ref<SysDict[]>([])
const tablePagination = reactive<PaginationProps>({
  simple: true,
  prefix: (info: PaginationInfo) => {
    return `共 ${info.itemCount} 条记录`
  },
  itemCount: 0,
  pageCount: 0
})

const modalDetailShow = ref(false)
const modalDetailType = ref<ModeTypeEnum>()
const modalDetailModel = reactive<SysDict>(<SysDict>{})
const modalDetailFormRef = ref<FormInst | null>()
const modalDetailSubmitLoading = ref(false)
const modalDetailFormRules = reactive<FormRules>({
  dictName: {required: true, message: '字典名称不能为空', trigger: 'blur'},
  dictCode: {required: true, message: '字典编码不能为空', trigger: 'blur'},
  dictStatus: {required: true, message: '字典状态不能为空', trigger: 'blur', type: 'number'},
  dictValueType: {required: true, message: '字典值类型不能为空', trigger: 'blur', type: 'number'},
})

onMounted(() => {
  dictStore.loadDict(['common-status', 'dict-value-type'])
  handlePageQuery()
})
watch(() => ({
  pageSize: tablePagination.pageSize,
  page: tablePagination.page
}), () => {
  router.replace({
    query: {
      ...currentRoute.query, ...{
        pageSize: Number(tablePagination.pageSize),
        page: Number(tablePagination.page)
      }
    }
  })
})
const tableActionRender = (row: SysDict) => {
  return h(NSpace, {justify: 'center'}, {
    default: () => [
      renderPermission(h(NButton, {
        text: true,
        type: 'primary',
        class: 'vertical-middle',
        onClick: () => handleClickModify(row)
      }, {default: renderIcon('lucide:edit', {size: 18})}), 'dict:type:modify'),
      h(NPopconfirm, {onPositiveClick: handleClickDelete(row)}, {
        trigger: () => renderPermission(h(NButton, {
          text: true,
          type: 'error',
          class: 'vertical-middle',
        }, {default: renderIcon('lucide:trash-2', {size: 18})}), 'dict:delete'),
        default: () => `确定删除该(${row.dictName}/${row.dictCode})字典吗？`
      })
    ]
  })
}
const tableDictCodeRender = (row: SysDict) => {
  return h(NFlex, {}, {
    default: () => [
      h(NButton, {
        size: 'small',
        text: true,
        type: 'primary',
        onClick: handleClickDictCode(row)
      }, {default: () => row.dictCode}),
      clickCopyButton(row.dictCode)
    ]
  })
}
const handlePageQuery = () => {
  tableLoading.value = true;
  dictApi.page({
    ...pageQuery,
    current: tablePagination.page ?? 1,
    size: tablePagination.pageSize ?? 15
  }).then(res => {
    tableData.value = res.data.records
    tablePagination.itemCount = res.data.total
    tablePagination.pageCount = res.data.pages
    tablePagination.pageSize = res.data.size
    tablePagination.page = res.data.current
  }).finally(() => tableLoading.value = false)
}
const handleClickDelete = (row: SysDict) => () => {
  if (row.id != null) {
    dictApi.delete(row.id).then(res => {
      window.$message?.success(res.message)
      let query = deepClone(currentRoute.query);
      delete query.parentId
      router.replace({query})
      handlePageQuery()
    })
  }
}
const initModalDetail = (modelType: ModeTypeEnum) => {
  modalDetailShow.value = true
  modalDetailType.value = modelType
}
const handleClickAdd = () => {
  initModalDetail(ModeTypeEnum.ADD)
  modalDetailModel.dictStatus = dictStore.getDictDefault('common-status').dictValue as number
  modalDetailModel.dictValueType = dictStore.getDictDefault('dict-value-type').dictValue as number
}
const handleClickModify = (row: SysDict) => {
  if (row.id != null) {
    dictApi.detail(row.id).then(res => {
      Object.assign(modalDetailModel, res.data)
      initModalDetail(ModeTypeEnum.MODIFY)
    })
  }
}
const handleClickDictCode = (row: SysDict) => () => {
  router.replace({query: {...currentRoute.query, parentId: row.id}})
}

const handleModalClose = () => {
  modalDetailFormRef.value?.restoreValidation()
  resetToNull(modalDetailModel)
  handlePageQuery()
  modalDetailSubmitLoading.value = false
}
const handleClickSubmit = () => {
  modalDetailSubmitLoading.value = true
  modalDetailFormRef.value?.validate((errors) => {
    if (!errors) {
      switch (modalDetailType.value) {
        case ModeTypeEnum.ADD:
          dictApi.addType(modalDetailModel).then(res => {
            window.$message?.success(res.message)
            modalDetailShow.value = false
          })
          break
        case ModeTypeEnum.MODIFY:
          dictApi.modifyType(modalDetailModel).then(res => {
            window.$message?.success(res.message)
            modalDetailShow.value = false
          })
      }
    }
  }).finally(() => modalDetailSubmitLoading.value = false)
}
</script>

<template>
  <n-card class="dict-type" w-500px h-fit>
    <template #header>
      <n-flex :wrap="false">
        <n-input
            v-model:value="pageQuery.keyword"
            type="text"
            placeholder="字典名称/字典编码"
        />
        <n-button
            secondary
            @click="handlePageQuery"
            :loading="tableLoading"
            v-p="'dict:page'"
        >查询
        </n-button>
        <n-button
            secondary
            type="primary"
            @click="handleClickAdd"
            v-p="'dict:type:add'"
        >新增
        </n-button>
      </n-flex>
    </template>
    <n-data-table
        remote
        size="small"
        :bordered="false"
        :columns="tableColumns"
        :data="tableData"
        :loading="tableLoading"
        :pagination="tablePagination"
    />
  </n-card>
  <n-modal
      w500px
      v-model:show="modalDetailShow"
      :segmented="{content: true, footer: 'soft'}"
      :title="modalDetailType"
      preset="card"
      :auto-focus="false"
      :mask-closable="false"
      :on-after-leave="handleModalClose"
  >
    <n-form
        ref="modalDetailFormRef"
        :model="modalDetailModel"
        :rules="modalDetailFormRules"
    >
      <n-grid :cols="24" :x-gap="12">
        <n-form-item-gi v-if="modalDetailModel.id" :span="24" label="主键">
          <n-tag type="primary">{{ modalDetailModel.id }}</n-tag>
        </n-form-item-gi>
        <n-form-item-gi :span="12" label="字典名称" path="dictName">
          <n-input v-model:value="modalDetailModel.dictName" placeholder="请输入字典名称" clearable/>
        </n-form-item-gi>
        <n-form-item-gi :span="12" label="字典编码(kebab-case)" path="dictCode">
          <n-input v-model:value="modalDetailModel.dictCode" placeholder="请输入字典编码" clearable/>
        </n-form-item-gi>
        <n-form-item-gi :span="12" label="字典值类型" path="dictValueType">
          <n-select
              :disabled="modalDetailType === ModeTypeEnum.MODIFY"
              v-model:value="modalDetailModel.dictValueType"
              :options="dictStore.getDictTagOptions('dict-value-type')"
              placeholder="请选择字典类型"
          />
        </n-form-item-gi>
        <n-form-item-gi :span="12" label="状态" path="dictStatus">
          <n-select
              v-model:value="modalDetailModel.dictStatus"
              :options="dictStore.getDictTagOptions('common-status')"
              placeholder="请选择状态"
          />
        </n-form-item-gi>
        <n-form-item-gi :span="24" label="字典描述" path="dictDesc">
          <n-input v-model:value="modalDetailModel.dictDesc" type="textarea" placeholder="请输入字典描述"/>
        </n-form-item-gi>
      </n-grid>
    </n-form>
    <template #action>
      <n-space justify="end">
        <n-button @click="modalDetailShow = false">取消</n-button>
        <n-button type="primary" @click="handleClickSubmit" :loading="modalDetailSubmitLoading">提交</n-button>
      </n-space>
    </template>
  </n-modal>
</template>

<style scoped>

</style>
